import md5 from 'md5';

import React, {
    PureComponent
} from 'react';

import {
    Image
} from 'react-native';

import {
    Actions
} from 'react-native-router-flux';

import * as iap from './../../../utils/iap';

import {
    ImUi,
    Press,
    Socket,
    Layout,
    Dialog,
    Tip
} from './../../../components';

import Message from './index';

import Ajax from './../../../http';

import MoreView from './../components/more';

import connect from './../../../utils/connect'
import more_icon from './../../../images/more.png';

import chatAction from './../../../state/actions/chat';
import * as chatTypes from './../../../state/types/chat';

import userAction from './../../../state/actions/user';
import * as userTypes from './../../../state/types/user';

interface Props {
    user: any,
    chat: any,
    common: any,
    userId: number,
    nickName: string,
    chatActions: any,
    userActions: any
}

@connect([`user`, `chat`, `common`], {
    chatActions: chatAction,
    userActions: userAction
})
class ChatRoom extends PureComponent <Props> {
    private imUi: any = null;
    private removeListen: any = null;

    static defaultProps = {
        user:{},
        chat:{},
        common:{},
        userId:0,
        nickName:``,
        chatActions:{},
        userActions:{}
    }

    UNSAFE_componentWillMount() {
        this.removeListen = Socket.on(
            Socket.CONST.chat,
            this._onListenChat
        )
        Message.curChatUserId = this.userId;
        Message.curChatRoomId = this.roomId;
    }

    componentWillUnmount() {
        if (this.removeListen) {
            this.removeListen()
        }
        Message.curChatUserId = 0;
        Message.curChatRoomId = '';
    }

    private _onListenChat = (messages:Array<any>) => {
        messages = messages.filter((item:any) => (
            item.chatRoomId === this.roomId
        ))
        if (this.imUi) {
            this.imUi.appendMessages(messages);
        }
    }

    get userActions() {
        const {
            userActions
        } = this.props;
        return userActions;
    }

    get coinSetting() {
        const {
            common
        } = this.props;
        const {
            coinSetting = {}
        } = common;
        return coinSetting;
    }

    get saleCoin() {
        const {
            chat_view_sale
        } = this.coinSetting;
        const {
            coins = 0
        } = chat_view_sale
        return coins;
    }

    get historyList(): Array<any> {
        const {
            chat
        } = this.props;

        const {
            history = {}
        } = chat;

        return history[this.roomId] || [];
    }

    get chatActions() {
        const {
            chatActions
        } = this.props;
        return chatActions;
    }

    get loginUser(): any {
        const {
            user
        } = this.props;
        const {
            loginUser
        } = user;
        return loginUser || {};
    }

    get nickName() {
        const {
            nickName
        } = this.props;
        return nickName;
    }

    get curUserId() {
        const {
            userId = 0
        } = this.loginUser;
        return ~~userId;
    }

    get userId() {
        const {
            userId=0
        } = this.props;
        return ~~userId;
    }

    get queryPara() {
        const _map = (item: any) => item.chatHistoryId;
        const ids = this.historyList.map(_map).filter(v => !!v);
        const chatIds: Array<number> = !!ids.length ? ids : [0];
        const curFirstChatId = Math.min(...chatIds);
        return {
            isPush: false,
            chatRoomId: this.roomId,
            curFirstChatId: curFirstChatId
        }
    }

    get curLastId() {
        const _map = (item: any) => item.chatHistoryId;
        const ids = this.historyList.map(_map).filter(v => !!v);
        const chatIds: Array<number> = !!ids.length ? ids : [0]
        return Math.max(...chatIds);
    }

    private _renderRight = () => {
        return (
            <Press onPress={this._openMore}>
                <Image source={more_icon}/>
            </Press>
        )
    }

    componentDidMount() {
        this._getHistory();
        this.chatActions[
            chatTypes.clearMessageUnread
        ](this.roomId)
    }

    public _openMore = () => {
        const content = (
            <MoreView
                userId={this.userId}
                onBlocked={Actions.pop}
            />
        )

        Dialog.show(content,{
            direction:`bottom`,
            clickClose:true
        })
    }

    private _getHistory() {
        const {
            length
        } = this.historyList;

        //如果没有历史记录，请求历史消息的第一屏
        if (length <= 0) {
            this._fetchHistory();
        }
    }

    //更多历史数据
    private _onLoadHistory = (done:Function) => {
        this._fetchHistory(done, true)
    }

    //往后查询消息
    private _onLoadBottom = async (done:Function) => {
        let list = [];
        const _para = {
            chatRoomId: this.roomId,
            curLastChatId: this.curLastId
        }
        try {
            list = await this.chatActions[
                chatTypes.getMessageAfterList
            ](_para);
        }
        catch (e) {
            return Tip.warm({
                message: e.message
            })
        }
        done(list);
    }

    private async _fetchHistory(
        done?: Function,
        isPush: boolean = false
    ) {
        let list = [];
        try {
            const para = (
                this.queryPara
            )
            const _Para = {
                ...para,
                isPush: isPush
            }
            list = await this.chatActions[
                chatTypes.getHistoryList
                ](_Para)
        }
        catch (e) {
            Tip.warm({
                message: e.message
            })
        }
        done && done(list);
    }

    get roomId() {
        const userStr = [
            this.userId,
            this.curUserId
        ].sort().join(`:`);
        return md5(userStr);
    }

    private chatPaid() {
        return Ajax.get(`check/chat/paid`, {
            chatUserId: this.userId
        })
    }

    //升级
    private _onUpgrade = (resolve?:Function) => {
        iap.buyMember().then(() => (
            resolve && resolve()
        ))
    }

    private _onSendMessage = async (
        msg:any, send:Function, update:Function
    ) => {
        try {
            const {
                isPaid
            } = await this.chatPaid();

            if (!isPaid) {
                return this._onUpgrade();
            }
        }
        catch (e) {
            return Tip.warm({
                message: e.message
            })
        }
        const _Para = {
            ...msg,
            userId: this.userId
        }
        try {
            send(msg);
            const res = await (
                this.chatActions[
                    chatTypes.sendMessage
                ](_Para)
            )
            update(res);
        }
        catch (e) {
            Tip.warm({
                message: e.message
            })
        }
    }

    render() {
        return (
            <Layout
                scroll={false}
                padding={false}
                title={this.nickName}
                renderRight={this._renderRight}
            >
                <ImUi
                    author={this.loginUser}
                    chatRoomId={this.roomId}
                    ref={e => this.imUi = e}
                    onLoadBottom={this._onLoadBottom}
                    initialMessages={this.historyList}
                    onSendMessage={this._onSendMessage}
                    onLoadHistory={this._onLoadHistory}
                />
            </Layout>
        )
    }
}

export default ChatRoom;